﻿using System;
using System.Collections.Generic;
using System.ComponentModel.Design.Serialization;
using System.Linq;
using System.Text;
using System.Workflow.ComponentModel.Serialization;
using ICalendar;

namespace ICalendarActivities
{
    public class ListSerializer : WorkflowMarkupSerializer, IDesignerSerializationProvider
    {
        protected override bool CanSerializeToString(WorkflowMarkupSerializationManager serializationManager, object value)
        {
            return true;
        }

        protected override void OnBeforeSerialize(WorkflowMarkupSerializationManager serializationManager, object obj)
        {
            serializationManager.AddSerializationProvider(this);
            base.OnBeforeSerialize(serializationManager, obj);
        }

        protected override void OnAfterSerialize(WorkflowMarkupSerializationManager serializationManager, object obj)
        {
            base.OnAfterSerialize(serializationManager, obj);
            serializationManager.RemoveSerializationProvider(this);
        }

        protected override void OnBeforeDeserialize(WorkflowMarkupSerializationManager serializationManager, object obj)
        {
            serializationManager.AddSerializationProvider(this);
            base.OnBeforeDeserialize(serializationManager, obj);
        }

        protected override void OnAfterDeserialize(WorkflowMarkupSerializationManager serializationManager, object obj)
        {
            base.OnAfterDeserialize(serializationManager, obj);
            serializationManager.RemoveSerializationProvider(this);
        }

        protected override string SerializeToString(WorkflowMarkupSerializationManager serializationManager, object value)
        {
            List<Parameter> parameters = (List<Parameter>)value;
            StringBuilder stringValue = new StringBuilder();
            foreach (Parameter parameter in parameters)
            {
                stringValue.Append(string.Format("{0}:{1},", parameter.Name, parameter.Type.ToString()));
            }
            if (stringValue.Length > 0)
            {
                stringValue.Remove(stringValue.Length - 1, 1);
            }

            return stringValue.ToString();
        }

        protected override object DeserializeFromString(WorkflowMarkupSerializationManager serializationManager, Type propertyType, string value)
        {
            List<Parameter> paramList = new List<Parameter>();
            string stringValue = value as string;
            if (stringValue != string.Empty)
            {
                string[] parameters = stringValue.Split(',');
                for (int i = 0; i < parameters.Length; ++i)
                {
                    string[] paramValues = parameters[i].Split(':');
                    if (paramValues.Length != 2)
                    {
                        throw new InvalidOperationException();
                    }

                    Parameter parameter = new Parameter();
                    parameter.Name = paramValues[0];
                    switch (paramValues[1])
                    {
                        case "Integer":
                            parameter.Type = ParameterType.Integer;
                            break;
                        case "DateTime":
                            parameter.Type = ParameterType.DateTime;
                            break;
                        case "String":
                            parameter.Type = ParameterType.String;
                            break;
                    }

                    paramList.Add(parameter);
                }
            }

            return paramList;
        }

        #region IDesignerSerializationProvider Members

        public object GetSerializer(IDesignerSerializationManager manager, object currentSerializer, Type objectType, Type serializerType)
        {
            if (objectType == typeof(List<Parameter>))
            {
                return this;
            }
            else
            {
                return null;
            }
        }
        #endregion
    }
}
